package com.dycong.common.common;

import org.apache.log4j.Logger;


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Stream;

/**
 * Created by dycong on 2016/12/26.
 */
public class StringUtil {
    private static Logger logger = Logger.getLogger(StringUtil.class);

    private static final char[] hexCode = "0123456789ABCDEF".toCharArray();

    public StringUtil() {
    }

    /**
     * @see 生成MD5并转换为32长度的十六进制数
     */
    public String getMD5Str(String str) throws IOException {
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(str.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            System.out.print("NoSuchAlgorithmException caught!");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        byte[] byteArray = messageDigest.digest();

        StringBuffer md5StrBuff = new StringBuffer();
        for (byte b : byteArray) {
            md5StrBuff.append(hexCode[b >> 4 & 0xf]);
            md5StrBuff.append(hexCode[b & 0xf]);
        }
        return md5StrBuff.toString();
    }

    /**
     * @see 不如官档啊
     */
    public static String toHexString(byte[] bytes) {
        if (bytes == null) {
            return "";
        } else {
            StringBuffer sb = new StringBuffer();
            byte[] var2 = bytes;
            int var3 = bytes.length;

            for (int var4 = 0; var4 < var3; ++var4) {
                byte b = var2[var4];
                String hex = Integer.toHexString(b & 255);
                if (hex.length() == 1) {
                    sb.append("0");
                }
                sb.append(hex);
            }
            return sb.toString().toUpperCase();
        }
    }

    public static String getMd5HexByUtf8Encoding(String string) {
        return getMd5Hex(string, "UTF-8");
    }

    public static String getMd5Hex(String string, String encoding) {
        try {
            return getMd5Hex(string.getBytes(encoding));
        } catch (UnsupportedEncodingException var3) {
            throw new RuntimeException(var3);
        }
    }


    public void test() {
        String string = "i love the A3 girl";
        byte[] bytes = getMd5(string.getBytes());
        System.out.println(getMd5Hex(string.getBytes()));
    }

    public static String getMd5Hex(byte[] bytes) {
        byte[] md5 = getMd5(bytes);
        String md5Str = ByteArrayUtil.toHexString(md5);
        if (logger.isDebugEnabled()) {
            if (bytes.length > 1024) {
                logger.debug("MD5[ ... size > 1024 ] = " + md5Str);
            } else {
                logger.debug("MD5[ " + ByteArrayUtil.toHexString(bytes) + " ] = " + md5Str);
            }
        }
        return md5Str;
    }

    public static byte[] getMd5(byte[] bytes) {
        try {
            MessageDigest e = MessageDigest.getInstance("MD5");
            byte[] md5 = e.digest(bytes);
            return md5;
        } catch (NoSuchAlgorithmException var3) {
            throw new RuntimeException("never here", var3);
        }
    }

    public static String uuid() {
        UUID uuid = UUID.randomUUID();
        return uuid.toString();
    }

    public static String generatedRandomNumber(int n) {
        String random;
        for (random = ""; random.length() < n; random += (int) (Math.random() * 10.0D)) {
            ;
        }

        return random;
    }

    /**
     * @see 判断是否包含NULL或“”
     */
    public static boolean existEmptyString(String... strings) {
        return strings == null ? false : Arrays.stream(strings).filter((s) -> {
            return s == null || s.equals("");
        }).findAny().isPresent();
    }

    public static boolean isPhoneNumber(String string) {
        return string.matches("^1[34578]\\d{9}$");
    }

    public static String getFirstMatchByXmlTagName(String xml, String tagName) {
        String match = xml.replaceAll(".*" + tagName + "\\>(.*)\\</" + tagName + ".*", "$1");
        return match.equals(xml) ? "" : match;
    }

    public static String getTimestampRandom() {
        String dateStr = DateUtil.format(new Date(), "yyMMddHHmmss");
        String id = dateStr + randomSting(9);
        return id;
    }

    public static String randomSting(int length) {
        if (length < 1) {
            length = 1;
        } else if (length > 9) {
            length = 9;
        }

        int max = (int) Math.pow(10.0D, (double) length);
        int random = Double.valueOf(Math.random() * (double) max + 1.0D).intValue();
        return formatNumber((long) random, length);
    }

    public static String formatNumber(long number, int length) {
        String s = String.format("%0" + length + "d", new Object[]{Long.valueOf(number)});
        if (s.length() > length) {
            s = s.substring(length);
        }

        return s;
    }

    public static String mapToQueryString(Map<String, String[]> map) {
        String rtn = "";
        if (map != null) {
            Iterator var2 = map.keySet().iterator();

            label33:
            while (true) {
                String key;
                String[] values;
                do {
                    if (!var2.hasNext()) {
                        break label33;
                    }

                    key = (String) var2.next();
                    values = (String[]) map.get(key);
                } while (values == null);

                String[] var5 = values;
                int var6 = values.length;

                for (int var7 = 0; var7 < var6; ++var7) {
                    String value = var5[var7];
                    if (value != null) {
                        rtn = rtn + key + "=" + value + "&";
                    }
                }
            }
        }

        if (rtn.length() > 0) {
            rtn = rtn.substring(0, rtn.length() - 1);
        }

        return rtn;
    }

    public static void assertNotEmpty(String... args) {
        findEmpty(args).ifPresent((s) -> {
            new IllegalArgumentException("argument not be allowed empty");
        });
    }

    public static boolean isNotEmpty(String... args) {
        return !isEmpty(args);
    }

    public static boolean isEmpty(String... args) {
        return findEmpty(args).isPresent();
    }

    private static Optional<String> findEmpty(String... args) {
        return ((Stream) Arrays.stream(args).parallel()).map((s) -> {
            return s == null ? "" : s;
        }).filter(s -> s.equals("")).findAny();
    }

    public static String join(CharSequence delimiter, Collection collector) {
        if (collector == null) {
            return null;
        } else {
            Object[] xx = collector.toArray();
            String[] str = new String[collector.size()];

            for (int i = 0; i < xx.length; ++i) {
                str[i] = xx[i].toString();
            }

            return String.join(delimiter, str);
        }
    }

    public static String genTestOrderId(String prefix) {
        return "test" + prefix + System.currentTimeMillis();
    }

    public static String addMask(String content, int start, int count) {
        if (!isNotEmpty(new String[]{content})) {
            return content;
        } else {
            int length = content.length();
            int end = start + count;
            StringBuffer mask = new StringBuffer(content.substring(0, start));

            for (int i = 0; i < count; ++i) {
                mask.append("*");
            }

            mask.append(content.substring(end, length));
            return mask.toString();
        }
    }

    public static List[] splitListByStep(List list, int step) {
        int count = list.size() / step;
        if (count == 0) {
            return new List[]{list};
        }
        List[] lists;

        if (count * step < list.size())
            lists = new List[count + 1];
        else
            lists = new List[count];

        for (int i = 0; i < count; ) {
            lists[i] = list.subList(i * step, (++i) * step);
        }
        if (count * step < list.size()) {
            lists[count] = list.subList(count * step, list.size());
        }
        return lists;
    }

    /**
     * 比较版本号的大小,前者大则返回一个正数,后者大返回一个负数,相等则返回0
     * 当前仅支持纯数值型“.”分割的字符串版本号
     * @param version1 版本1
     * @param version2 版本2
     */
    public static int compareVersion(String version1, String version2) throws Exception {
        if (version1 == null || version2 == null) {
            throw new IllegalArgumentException("compareVersion error:illegal params.");
        }
        String[] versionArray1 = version1.split("\\.");//注意此处为正则匹配，不能用.；
        String[] versionArray2 = version2.split("\\.");
        int idx = 0;
        int minLength = Math.min(versionArray1.length, versionArray2.length);//取最小长度值
        int diff = 0;
        while (idx < minLength
                && (diff = versionArray1[idx].length() - versionArray2[idx].length()) == 0//先比较长度
                && (diff = versionArray1[idx].compareTo(versionArray2[idx])) == 0) {//再比较字符
            ++idx;
        }
        //如果已经分出大小，则直接返回，如果未分出大小，则再比较位数，有子版本的为大；
        diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length;
        return diff;
    }
}
